package br.com.gr.jcash.ctr;

import br.com.gr.jcash.dmp.Movimento;
import br.com.gr.jcash.dmp.TipoCategoria;
import br.com.gr.jcash.dto.ContaDTO;
import br.com.gr.jcash.exception.JCashException;
import br.com.gr.jcash.iface.ICategoriaBO;
import br.com.gr.jcash.iface.IContaBO;
import br.com.gr.jcash.iface.IMovimentoBO;
import br.com.gr.jcash.utils.Filtro;
import br.com.gr.jcash.util.JsfUtil;
import br.com.gr.jcash.relatorio.GeradorRelatorio;
import br.com.gr.jcash.utils.RelatorioHelper;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.model.SelectItem;
import net.sf.jasperreports.engine.JRException;

/**
 *
 * @author gelson
 */
@ManagedBean
@RequestScoped
public class RelatorioController implements Serializable {

    @EJB
    IMovimentoBO movimentoBO;
    @EJB
    ICategoriaBO categoriaBO;
    @EJB
    IContaBO contaBO;
    private SelectItem[] selectTipoCategoria;
    private SelectItem[] selectCategoria;
    private SelectItem[] selectConta;
    private SelectItem[] selectContaCapital;
    private Filtro filtro;

    public RelatorioController() {
    }

    @PostConstruct
    public void iniciar() {
        filtro = new Filtro();
    }

    public SelectItem[] getSelectTipoCategoria() {
        if (selectTipoCategoria == null) {
            List<TipoCategoria> tipoCategorias = Arrays.asList(TipoCategoria.D,TipoCategoria.R);
            selectTipoCategoria = JsfUtil.getSelectItems(tipoCategorias, true);
            filtro.setCategoria(null);
            filtro.setConta(null);
        }
        return selectTipoCategoria;
    }

    public SelectItem[] getSelectConta() {
        try {
            if (null == filtro.getCategoria() && null == filtro.getTipoCategoria()) {
                selectConta = JsfUtil.getSelectItems(contaBO.buscarContaPorTipoCategoria(TipoCategoria.D,TipoCategoria.R), true);
            } else if (null != filtro.getCategoria()) {
                selectConta = JsfUtil.getSelectItems(contaBO.buscarContaPorCategoria(filtro.getCategoria()), true);
            } else {
                selectConta = JsfUtil.getSelectItems(contaBO.buscarContaPorTipoCategoria(filtro.getTipoCategoria()), true);
            }
        } catch (JCashException ex) {
            JsfUtil.addErrorMessage(ex, "Falha ao obter a lista de contas!");
        }
        return selectConta;
    }

    public SelectItem[] getSelectContaCapital() {
        try {
            selectContaCapital = JsfUtil.getSelectItems(contaBO.buscarContaPorTipoCategoria(TipoCategoria.C), true);
        } catch (JCashException ex) {
            JsfUtil.addErrorMessage(ex, "Falha ao obter a lista de contas!");
        }
        return selectContaCapital;
    }

    public SelectItem[] getSelectCategoria() {
        try {
            if (null == filtro.getTipoCategoria()) {
                selectCategoria = JsfUtil.getSelectItems(categoriaBO.buscarPorTipo(TipoCategoria.D, TipoCategoria.R), true);
                filtro.setConta(null);
            } else {
                selectCategoria = JsfUtil.getSelectItems(categoriaBO.buscarPorTipo(filtro.getTipoCategoria()), true);
                filtro.setConta(null);
            }
        } catch (JCashException ex) {
            JsfUtil.addErrorMessage(ex, "Falha ao obter a lista de categoria!");
        }
        return selectCategoria;
    }

    public Filtro getFiltro() {
        return filtro;
    }

    public void setFiltro(Filtro filtro) {
        this.filtro = filtro;
    }

    public void gerarRelatorioLancamento() {
        if (filtro.getDataInicial().after(filtro.getDataFinal())) {
            JsfUtil.addErrorMessage("Data inicial posterior a data final!");
        } else {
            List<Movimento> lista = null;
            try {
                lista = movimentoBO.buscarRelatorio(filtro);
            } catch (JCashException ex) {
                JsfUtil.addErrorMessage(ex, "Falha ao obter o(s) movimento(s)!");
                return;
            }

            if (null == lista || lista.isEmpty()) {
                JsfUtil.addWarningMessage("Nenhum registro encontrado com o filtro informado!");
            } else {
                GeradorRelatorio gerador = new GeradorRelatorio();
                HashMap<String, Object> map = new HashMap<>();
                map.put("login", JsfUtil.getUsuarioLogado());
                map.put("dataInicial", filtro.getDataInicial());
                map.put("dataFinal", filtro.getDataFinal());
                try {
                    gerador.gerarRelatorioWeb(lista, "RelatorioLancamento", map);
                } catch (IOException ex) {
                    JsfUtil.addErrorMessage(ex, "Falha ao obter o arquivo do relatório!");
                } catch (JRException ex) {
                    JsfUtil.addErrorMessage(ex, "Falha ao gerar o relatório!");
                }
            }
        }
    }

    public void gerarRelatorioExtrato() {
        if (filtro.getDataInicial().after(filtro.getDataFinal())) {
            JsfUtil.addErrorMessage("Data inicial posterior a data final!");
        } else {
            RelatorioHelper helper;
            List<ContaDTO> lista = null;
            try {
                helper = contaBO.buscarExtrato(filtro);
                lista = helper.getLista();
            } catch (JCashException ex) {
                JsfUtil.addErrorMessage(ex, "Falha ao obter o(s) movimento(s)!");
                return;
            }

            if (null == lista || lista.isEmpty()) {
                JsfUtil.addWarningMessage("Nenhum registro encontrado com o filtro informado!");
            } else {
                GeradorRelatorio gerador = new GeradorRelatorio();
                HashMap<String, Object> map = new HashMap<>();
                map.put("login", JsfUtil.getUsuarioLogado());
                map.put("dataInicial", filtro.getDataInicial());
                map.put("dataFinal", filtro.getDataFinal());
                map.put("conta", filtro.getConta().getIdCta()+" - " + filtro.getConta().getCtaDescricao());
                map.put("saldoAnterior",helper.getSaldoAnterior());
                try {
                    gerador.gerarRelatorioWeb(lista, "ExtratoConta", map);
                } catch (IOException ex) {
                    JsfUtil.addErrorMessage(ex, "Falha ao obter o arquivo do relatório!");
                } catch (JRException ex) {
                    JsfUtil.addErrorMessage(ex, "Falha ao gerar o relatório!");
                }
            }
        }
    }
}